package com.grass.cropTradingCenter.service.impl;

import com.grass.cropTradingCenter.common.OutputException;
import com.grass.cropTradingCenter.pojo.dto.KafkaSendEmailDto;
import com.grass.cropTradingCenter.service.EmailService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeUtility;
import java.time.Duration;
import java.util.Date;
import java.util.Random;
import java.util.regex.Pattern;

@Service
public class EmailServiceImpl implements EmailService {

    @Autowired
    private JavaMailSender mailSender;


    @Value("${grass.idCodeNum}")
    Integer idCodeNum;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Lazy
    @Autowired
    private EmailService emailService;

    @Autowired
    private KafkaTemplate<Object, Object> kafkaTemplate;

    public SimpleMailMessage getMessage(String toEmail, String idCode)  {
        SimpleMailMessage message = new SimpleMailMessage();
//        message.setFrom("li18530794371@163.com");
        try {
            message.setFrom(new InternetAddress(MimeUtility.encodeText("农贸市场中心")+"<li18530794371@163.com>").toString());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        message.setTo(toEmail);
        message.setSubject("【农贸市场中心】");
        message.setText("验证码:" + idCode +
                "，本验证码15分钟内有效，如非本人操作请忽略。请勿提供验证码给他人，避免账号被盗或信息泄露！");
        message.setSentDate(new Date());
        return  message;
    }

    private final String REDIS_KEY_EMAIL_CODE = "EMAIL_CODE#";
    /**
     * 发送验证码
     * @param dto
     */
    @Override
    public void consumeEmailCode(KafkaSendEmailDto dto){
        // 保存到Redis中
        redisTemplate.opsForValue().set(getIdCodeKey(dto.getEmail()), dto.getIdCode(), Duration.ofMinutes(15));
        // 发送信息 todo 打开注释
//        mailSender.send(getMessage(dto.getEmail(), dto.getIdCode()));
        // 发送给自己的邮箱
        mailSender.send(getMessage("201582234@qq.com", dto.getIdCode()));
    }

    @Override
    public void checkIdCode(String email, String idCode) {
        checkEmail(email);
        if(StringUtils.isBlank(idCode)) throw new OutputException("验证码不能为空");
        String key = getIdCodeKey(email);
        String redisIdCode = redisTemplate.opsForValue().get(key);
        if(StringUtils.isBlank(redisIdCode)) throw new OutputException("验证码无效");
        if(!redisIdCode.equals(idCode)) throw new OutputException("验证码错误");
    }


    public String getIdCodeKey(String email){
        return REDIS_KEY_EMAIL_CODE + email;
    }

    @Override
    public void sendCode(String toEmail){
        checkEmail(toEmail);
        /**
         * 生成验证码
         */
        Random random = new Random();
        StringBuilder idCodeBuilder =  new StringBuilder("");
        for (int i = 1; i <= idCodeNum; i++){
            idCodeBuilder.append(random.nextInt(10));
        }
        // todo 注释下面一句话
        emailService.consumeEmailCode(new KafkaSendEmailDto(toEmail, idCodeBuilder.toString()));
        System.out.println("验证码：" + idCodeBuilder.toString());
        // todo 打开注释
//        kafkaTemplate.send("SendEmail", new KafkaSendEmailDto(toEmail, idCodeBuilder.toString()));

    }


    /**
     * 验证Email
     * @param email email地址
     * @return --true 是邮箱   --false 不是邮箱
     */
    public void checkEmail(String email){
        String regex = "\\w+@\\w+\\.[a-z]+(\\.[a-z]+)?";
        if(!Pattern.matches(regex, email)){
            throw new OutputException("邮箱格式不正确");
        }
    }
}
